package com.bac.rentmap.ad.crawler.stepped.predicate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.bac.rentmap.ad.crawler.AdCrawler;
import com.bac.rentmap.ad.crawler.Context;
import com.bac.rentmap.ad.crawler.CrawledAd;
import com.bac.rentmap.ad.crawler.stepped.SteppedAdCrawler;

/**
 * Crawls data using {@link SteppedAdCrawler}. Crawled ad count is controlled by
 * {@link RelevancePredicate}.
 * 
 * @author Andrew Osipenko
 * 
 * @param <T>
 */
public abstract class AbstractPredicateAdCrawler<T extends CrawledAd>
		implements AdCrawler<T> {
	private int maxCount = 10;

	public List<T> crawl(Context context) throws IOException {
		SteppedAdCrawler<T> steppedAdCrawler = buildSteppedAdCrawler(context);
		steppedAdCrawler = decorateSteppedAdCrawler(steppedAdCrawler);
		List<T> crawledAds;
		List<T> res = new ArrayList<T>();
		for(int i = 0; i < 7; i++){
			
			crawledAds = steppedAdCrawler.crawlNext();
			if (crawledAds != null)
				res.addAll(crawledAds);
			else
				return res;
		}
		throw new RuntimeException("Can't crawl enough data");
	}

	private SteppedAdCrawler<T> decorateSteppedAdCrawler(
			SteppedAdCrawler<T> steppedAdCrawler) {
		PredicateSteppedAdCrawler<T> res = new PredicateSteppedAdCrawler<T>(
				steppedAdCrawler, new CountRestrictingRelevancePredicate<T>(
						maxCount));
		return res;
	}

	public void setMaxCount(int maxCount) {
		this.maxCount = maxCount;
	}

	protected abstract SteppedAdCrawler<T> buildSteppedAdCrawler(Context context);
}
